home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / dev / basic / ace24dist.lha / ace24.lha / ReqEd / Source / ReqEd.b < prev    next >
Text File  |  1996-09-12  |  50KB  |  1,890 lines

  1. {*
  2. ** A Requester Editor for ACE programs.
  3. **
  4. ** A requester (in this context, a window containing gadgets and text)
  5. ** can be designed on-screen. Code, in the form of an ACE subprogram, 
  6. ** is then generated to render it, await gadget activity and clean up.
  7. **
  8. ** The programmer can add code to act upon specific gadget activity 
  9. ** and possibly return information to the main program.
  10. **
  11. ** Author: David J Benn
  12. **   Date: 6th-8th,10th,15th-22nd,25th,26th January 1995,
  13. **       13th,14th,18th-20th February 1995,
  14. **       12th September 1996
  15. *}
  16.  
  17. DEFLNG a-z
  18.  
  19. STRING version SIZE 30
  20. version = "$VER: ReqEd 1.12 (12.09.96)"
  21.  
  22. {*
  23. ** General constants.
  24. *}
  25. CONST true     = -1&
  26. CONST false     = 0&
  27. CONST null     = 0&
  28. CONST default     = -1&
  29.  
  30. {*
  31. ** ASCII codes for special keys.
  32. *}
  33. CONST DEL_key     = 127
  34. CONST BKSPC_key = 8
  35. CONST ENTER_key = 13
  36.  
  37. {*
  38. ** Border constants.
  39. *}
  40. CONST NO_EDGE        = 0 
  41. CONST LEFT_EDGE        = 1 
  42. CONST RIGHT_EDGE    = 2 
  43. CONST TOP_EDGE        = 3 
  44. CONST BOTTOM_EDGE    = 4
  45. CONST EDGE_THICKNESS    = 2
  46.  
  47. {*
  48. ** Menu constants.
  49. *}
  50. CONST sDisable        = 0
  51. CONST sEnable        = 1
  52. CONST sCheck        = 2
  53.  
  54. CONST mProject        = 1
  55. CONST iProject        = 0
  56. CONST iExit         = 1    '..for Preview mode Project menu.
  57. CONST iNew        = 1    '..for Layout mode Project menu.
  58. CONST iOpen        = 2
  59. CONST iSave        = 3
  60. CONST iSaveAs        = 4
  61. CONST iToolBar        = 5
  62. CONST iSep1.1        = 6
  63. CONST iAbout        = 7
  64. CONST iQuit        = 8
  65.  
  66. CONST mWindow        = 2
  67. CONST iWindow        = 0
  68. CONST iRedraw        = 1
  69. CONST iPreview        = 2
  70. CONST iSep2.1        = 3
  71. CONST iSetId        = 4
  72. CONST iSetTitle        = 5
  73. CONST iSep2.2        = 6
  74. CONST iSizeGadget    = 7
  75. CONST iMoveable        = 8
  76. CONST iDepthGadget    = 9
  77. CONST iCloseGadget    = 10
  78. CONST iSmartRefresh    = 11
  79. CONST iBorderless    = 12
  80.  
  81. {*
  82. ** Gadget constants.
  83. *}
  84. CONST gButton        = 1
  85. CONST gString        = 2
  86. CONST gLongInt        = 3
  87. CONST gPotX        = 4
  88. CONST gPotY        = 5
  89. CONST gText        = 6
  90. CONST gRaisedBox    = 7
  91. CONST gRecessedBox    = 8
  92.  
  93. {*
  94. ** GUI Object List node "kinds" (note: values agree with gadget constants above).
  95. *}
  96. CONST headOfList     = 0
  97. CONST buttonGadget     = 1
  98. CONST stringGadget     = 2
  99. CONST longintGadget     = 3
  100. CONST potXGadget     = 4
  101. CONST potYGadget     = 5
  102. CONST staticText     = 6
  103. CONST raisedBevelBox    = 7
  104. CONST recessedBevelBox    = 8
  105.  
  106. {*
  107. ** Box styles.
  108. *}
  109. CONST NORMAL         = 0
  110. CONST RAISED         = 1
  111. CONST RECESSED         = 2
  112. CONST STRGAD         = 3
  113.  
  114. {*
  115. ** Miscellaneous constants.
  116. *}
  117. CONST toolWdw = 1
  118. CONST maxToolBarButtons = 8
  119.  
  120. {* 
  121. ** Structure definitions.
  122. *}
  123. STRUCT WindowStruct
  124.    ADDRESS  NextWindow
  125.    SHORTINT LeftEdge
  126.    SHORTINT TopEdge
  127.    SHORTINT xWidth
  128.    SHORTINT Height
  129.    SHORTINT MouseY
  130.    SHORTINT MouseX
  131.    SHORTINT MinWidth
  132.    SHORTINT MinHeight
  133.    SHORTINT MaxWidth
  134.    SHORTINT MaxHeight
  135.    LONGINT  Flags
  136.    ADDRESS  MenuStrip
  137.    ADDRESS  Title
  138.    ADDRESS  FirstRequest
  139.    ADDRESS  DMRequest
  140.    SHORTINT ReqCount
  141.    ADDRESS  WScreen
  142.    ADDRESS  RPort
  143.    BYTE     BorderLeft
  144.    BYTE     BorderTop
  145.    BYTE     BorderRight
  146.    BYTE     BorderBottom
  147.    ADDRESS  BorderRPort
  148.    ADDRESS  FirstGadget
  149.    ADDRESS  Parent
  150.    ADDRESS  Descendant
  151.    ADDRESS  Pointer
  152.    BYTE     PtrHeight
  153.    BYTE     PtrWidth
  154.    BYTE     XOffset
  155.    BYTE     YOffset
  156.    LONGINT  IDCMPFlags
  157.    ADDRESS  UserPort
  158.    ADDRESS  WindowPort
  159.    ADDRESS  MessageKey
  160.    BYTE     DetailPen
  161.    BYTE     BlockPen
  162.    ADDRESS  CheckMark
  163.    ADDRESS  ScreenTitle
  164.    SHORTINT GZZMouseX
  165.    SHORTINT GZZMouseY
  166.    SHORTINT GZZWidth
  167.    SHORTINT GZZHeight
  168.    ADDRESS  ExtData
  169.    ADDRESS  UserData
  170.    ADDRESS  WLayer
  171.    ADDRESS  IFont
  172. END STRUCT
  173.  
  174. STRUCT GUIObjType
  175.   SHORTINT kind
  176.   SHORTINT x1
  177.   SHORTINT y1
  178.   SHORTINT x2
  179.   SHORTINT y2
  180.   ADDRESS  theText
  181.   ADDRESS  fontName
  182.   SHORTINT fontHeight
  183.   SHORTINT textStyle
  184.   SHORTINT frontColor
  185.   SHORTINT backColor
  186.   LONGINT  potVal
  187.   ADDRESS  nextNode
  188. END STRUCT
  189.  
  190. STRUCT CoordType
  191.   SHORTINT x1
  192.   SHORTINT y1
  193.   SHORTINT x2
  194.   SHORTINT y2
  195.   LONGINT  valid
  196. END STRUCT
  197.  
  198. STRUCT FontInfo
  199.   ADDRESS  fontName
  200.   SHORTINT fontHeight  
  201.   SHORTINT textStyle
  202.   SHORTINT frontColor
  203.   SHORTINT backColor
  204. END STRUCT
  205.  
  206. {*
  207. ** Globals.
  208. *}
  209. LONGINT finished
  210. LONGINT wdwFlags, wdwID, dirty, toolBarActive
  211. SHORTINT wdw_x1, wdw_y1, wdw_x2, wdw_y2
  212. SHORTINT old_wdw_x1, old_wdw_y1
  213. SHORTINT gadCount
  214. STRING wdwTitle SIZE 100
  215. STRING projectName SIZE 80
  216. STRING reqName SIZE 80
  217. DECLARE STRUCT GUIObjType *guiObjList
  218. ADDRESS spriteData
  219. DIM STRING buttonText(maxToolBarButtons) SIZE 15
  220.  
  221. {*
  222. ** Shared library function declarations.
  223. *}
  224. LIBRARY "graphics.library"
  225. DECLARE FUNCTION SetDrMd(ADDRESS RPort, SHORTINT mode) LIBRARY graphics
  226. DECLARE FUNCTION SHORTINT TextLength(ADDRESS RPort, STRING theText, ~
  227.                      SHORTINT count) LIBRARY graphics
  228.  
  229. LIBRARY "intuition.library"
  230. DECLARE FUNCTION SetPointer(ADDRESS wdw,ADDRESS spData,h%,w%,xOff%,yOff%) LIBRARY intuition
  231. DECLARE FUNCTION SetWindowTitles(ADDRESS wdw,wdw_title$,scr_title$) LIBRARY intuition
  232. CONST LEAVE = -1&
  233.  
  234. {*
  235. ** External SUB declarations.
  236. *}
  237. DECLARE SUB LONGINT FontInfoRequest(ADDRESS fontInfoStruct) EXTERNAL
  238.  
  239. '..See external references section in FontReq.b re: the following kludge!
  240. ASSEM 
  241.   xdef _EXIT_PROG
  242. END ASSEM
  243.  
  244. {*
  245. ** Forward SUB references.
  246. *}
  247. DECLARE SUB RedrawGUIObjects
  248. DECLARE SUB ADDRESS GUIObjVal(ADDRESS guiObjAddr, STRING prompt)
  249.  
  250. {*
  251. ** Subprogram definitions.
  252. *}
  253.  
  254. {* General SUBs *}
  255. SUB InitToolBarButtonText
  256. SHARED buttonText
  257. SHORTINT i
  258.   FOR i=1 TO maxToolBarButtons
  259.     READ buttonText(i)
  260.   NEXT
  261.   DATA "Button", "String", "LongInt", "PotX", "PotY", "Text"
  262.   DATA "Plateau", "Panel"
  263. END SUB
  264.  
  265. SUB InitCrossHairPointerData
  266. SHARED spriteData
  267. SHORTINT bytes, i, theWord
  268. CONST numberOfPairs = 17
  269.  
  270.   bytes = numberOfPairs*2*SIZEOF(SHORTINT)
  271.   spriteData = ALLOC(bytes,0)    '..allocate CHIP memory for sprite data.
  272.  
  273.   IF spriteData <> null THEN
  274.     FOR i=0 TO bytes-1 STEP 2
  275.       READ theWord
  276.       *%(spriteData+i) := theWord
  277.     NEXT
  278.  
  279.     DATA 0,0    '..position, control
  280.  
  281.     DATA &H0000, &H0000
  282.     DATA &H0000, &H0000
  283.  
  284.     DATA &H0100, &H0000
  285.     DATA &H0100, &H0000
  286.     DATA &H0100, &H0000
  287.     DATA &H0100, &H0000
  288.  
  289.     DATA &H0000, &H0000
  290.     DATA &HFD7E, &H0000
  291.     DATA &H0000, &H0000
  292.  
  293.     DATA &H0100, &H0000
  294.     DATA &H0100, &H0000
  295.     DATA &H0100, &H0000
  296.     DATA &H0100, &H0000
  297.  
  298.     DATA &H0000, &H0000    
  299.     DATA &H0000, &H0000    
  300.     
  301.     DATA 0,0    '..end
  302.   END IF
  303. END SUB
  304.  
  305. SUB LTRIM$(STRING x)
  306. SHORTINT i
  307.   FOR i=1 TO LEN(x)
  308.     IF MID$(x,i,1) <> " " THEN EXIT FOR 
  309.   NEXT
  310.   LTRIM$ = MID$(x,i)
  311. END SUB
  312.  
  313. SUB SetCurrWdw
  314. SHARED toolBarActive, wdwID
  315. SHORTINT currWdw
  316.   IF NOT toolBarActive THEN 
  317.     WINDOW OUTPUT wdwID
  318.   ELSE
  319.     currWdw = WINDOW(0)
  320.     IF currWdw = wdwID OR currWdw = toolWdw THEN WINDOW OUTPUT currWdw
  321.   END IF
  322. END SUB
  323.  
  324. SUB SetWdwRect
  325. SHARED wdwID, toolBarActive, dirty
  326. SHARED old_wdw_x1, old_wdw_y1
  327. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  328. DECLARE STRUCT WindowStruct *wdw
  329.   WINDOW OUTPUT wdwID
  330.   wdw = WINDOW(7)
  331.   wdw_x1 = wdw->LeftEdge
  332.   wdw_y1 = wdw->TopEdge
  333.   wdw_x2 = wdw_x1 + WINDOW(2)
  334.   wdw_y2 = wdw_y1 + WINDOW(3)
  335.   IF toolBarActive THEN WINDOW OUTPUT toolWdw
  336.   IF wdw_x1 <> old_wdw_x1 OR wdw_y1 <> old_wdw_y1 THEN 
  337.     dirty = true
  338.     old_wdw_x1 = wdw_x1
  339.     old_wdw_y1 = wdw_y1
  340.   END IF
  341. END SUB
  342.  
  343. SUB STRING Rect(SHORTINT x1,SHORTINT y1,SHORTINT x2,SHORTINT y2)
  344.   Rect = "("+LTRIM$(STR$(x1))+","+LTRIM$(STR$(y1))+")-("+ ~
  345.      LTRIM$(STR$(x2))+","+LTRIM$(STR$(y2))+")"
  346. END SUB
  347.  
  348. SUB ShowMouseCoordinates(SHORTINT x1, SHORTINT y1, SHORTINT x2, SHORTINT y2)
  349. SHARED wdwID, wdwFlags, wdwTitle
  350.   WINDOW OUTPUT wdwID
  351.   IF (wdwFlags AND 2) OR (wdwFlags AND 4) OR (wdwFlags AND 8) OR (wdwTitle <> "") THEN 
  352.     SetWindowTitles(WINDOW(7),    "("+LTRIM$(STR$(x1))+","+ ~
  353.                 LTRIM$(STR$(y1))+")-("+ ~
  354.                 LTRIM$(STR$(x2))+","+ ~
  355.                 LTRIM$(STR$(y2))+")", ~
  356.             LEAVE)
  357.   END IF
  358. END SUB
  359.  
  360. SUB ResetReqWdwTitle
  361. SHARED wdwID, wdwFlags, wdwTitle
  362.   WINDOW OUTPUT wdwID
  363.   IF wdwTitle <> "" THEN
  364.     SetWindowTitles(WINDOW(7),wdwTitle,LEAVE)
  365.   ELSE
  366.     IF (wdwFlags AND 2) OR (wdwFlags AND 4) OR (wdwFlags AND 8) THEN
  367.       SetWindowTitles(WINDOW(7),"",LEAVE)
  368.     END IF
  369.   END IF
  370. END SUB
  371.  
  372. SUB CreateWindow
  373. SHARED wdwTitle, wdwFlags, wdwID
  374. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  375. SHARED spriteData
  376.   IF wdwFlags AND 2 THEN
  377.     '..Moveable, so need a title bar.
  378.     WINDOW wdwID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  379.   ELSE
  380.     IF wdwTitle <> "" THEN
  381.       '..A title has been specified.
  382.       WINDOW wdwID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  383.     ELSE
  384.       '..No title specified.
  385.       WINDOW wdwID,,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  386.     END IF
  387.   END IF
  388.  
  389.   '..Set the window's mouse pointer.
  390.   IF spriteData <> null THEN CALL SetPointer(WINDOW(7), spriteData, 15, 15, -8, -7)
  391.  
  392.   '..Redraw gadgets and text.
  393.   RedrawGUIObjects
  394. END SUB
  395.  
  396. SUB SetupMenus
  397. SHARED toolBarActive, wdwFlags
  398. SHORTINT i
  399.   MENU mProject,iProject,sEnable,    "Project"
  400.   MENU mProject,iNew,sEnable,        "   New",    "N"
  401.   MENU mProject,iOpen,sEnable,        "   Open...",    "O"
  402.   MENU mProject,iSave,sEnable,        "   Save...",    "S"
  403.   MENU mProject,iSaveAs,sEnable,    "   Save As..."
  404.   MENU mProject,iToolBar,sEnable,    "   Tool Bar",    "T"
  405.   MENU mProject,iSep1.1,sDisable,    "-----------------"
  406.   MENU mProject,iAbout,sEnable,        "   About..."
  407.   MENU mProject,iQuit,sEnable,        "   Quit",    "Q"
  408.  
  409.   MENU mWindow,iWindow,sEnable,        "Window"
  410.   MENU mWindow,iRedraw,sEnable,        "   Redraw",    "R"
  411.   MENU mWindow,iPreview,sEnable,    "   Preview",    "P"
  412.   MENU mWindow,iSep2.1,sDisable,    "----------------"
  413.   MENU mWindow,iSetId,sEnable,        "   Set Id..."
  414.   MENU mWindow,iSetTitle,sEnable,    "   Set Title..."
  415.   MENU mWindow,iSep2.2,sDisable,    "----------------"
  416.   MENU mWindow,iSizeGadget,sEnable,    "   Size Gadget"
  417.   MENU mWindow,iMoveable,sEnable,    "   Moveable"
  418.   MENU mWindow,iDepthGadget,sEnable,    "   Depth Gadget"
  419.   MENU mWindow,iCloseGadget,sEnable,    "   Close Gadget"
  420.   MENU mWindow,iSmartRefresh,sEnable,    "   Smart Refresh"
  421.   MENU mWindow,iBorderless,sEnable,    "   Borderless"
  422.  
  423.   '..Is the Tool Bar window active?
  424.   IF toolBarActive THEN MENU mProject,iToolBar,sCheck
  425.  
  426.   '..Set window menu checkmarks.
  427.   FOR i=0 TO 5
  428.     IF wdwFlags AND CINT(2^i) THEN MENU mWindow,iSizeGadget+i,sCheck
  429.   NEXT 
  430. END SUB
  431.  
  432. SUB DrawTextLayoutGuide(SHORTINT x1, SHORTINT y1, SHORTINT x2, SHORTINT y2)
  433.   '..Left edge of layout guide 
  434.   '..(possibly adjust, since it may have grown in 
  435.   '..height due to large font being specified while 
  436.   '..near top of window).
  437.   IF y1 < 0 THEN y1 = 0
  438.   LINE (x1,y1)-(x1,y2),2
  439.  
  440.   '..Text length indicator.
  441.   LINE (x1,y2)-(x2,y2),2
  442. END SUB
  443.  
  444. {* GUI Object List related SUBs/FNs *}
  445.  
  446. DEF ADDRESS NewGUIObj = ALLOC(SIZEOF(GUIObjType))
  447.  
  448. SUB ADDRESS GUIObjListHead
  449. SHARED guiObjList
  450.   guiObjList = NewGUIObj
  451.  
  452.   IF guiObjList = null THEN 
  453.     MsgBox "Memory allocation error!","Continue"
  454.   END IF
  455.  
  456.   guiObjList->kind = headOfList
  457.  
  458.   GUIObjListHead = guiObjList
  459. END SUB
  460.  
  461. SUB LONGINT NodesOK(ADDRESS theNode)
  462. SHARED guiObjList
  463.   IF guiObjList = null THEN
  464.     MsgBox "GUI Object List is not initialised!","Continue"
  465.     NodesOK = false
  466.     EXIT SUB
  467.   END IF
  468.   
  469.   IF theNode = null THEN
  470.     MsgBox "GUI Object Node is null!","Continue"
  471.     NodesOK = false
  472.     EXIT SUB
  473.   END IF
  474.  
  475.   NodesOK = true
  476. END SUB
  477.  
  478. SUB LONGINT NodesMatch(ADDRESS a, ADDRESS b)
  479. DECLARE STRUCT GUIObjType *node1, *node2
  480.   node1 = a
  481.   node2 = b
  482.  
  483.   IF node1->kind = node2->kind AND ~
  484.      node1->x1 = node2->x1 AND node1->y1 = node2->y1 AND ~
  485.      node1->x2 = node2->x2 AND node1->y2 = node2->y2 THEN
  486.     '..They are equal.
  487.     NodesMatch = true
  488.   ELSE
  489.     '..They are different.
  490.     NodesMatch = false
  491.   END IF
  492. END SUB
  493.  
  494. SUB AddGUIObj(ADDRESS theNode)
  495. SHARED guiObjList, gadCount
  496. DECLARE STRUCT GUIObjType *curr
  497.   IF NodesOK(theNode) THEN
  498.     '..Seek end of the list.   
  499.     curr = guiObjList
  500.     WHILE curr->nextNode <> null
  501.       curr = curr->nextNode
  502.     WEND
  503.  
  504.     '..Add the new node.
  505.     IF GadCount <= 255 THEN
  506.       IF curr->kind >= buttonGadget AND curr->kind <= potYGadget THEN ++gadCount
  507.       curr->nextNode = theNode
  508.     END IF
  509.   END IF
  510. END SUB
  511.  
  512. SUB RemoveGUIObj(ADDRESS theNode)
  513. SHARED guiObjList, gadCount
  514. DECLARE STRUCT GUIObjType *prev, *curr
  515. LONGINT found
  516.   IF NodesOK(theNode) THEN
  517.     '..Find node.
  518.     prev = guiObjList
  519.     curr = guiObjList->nextNode
  520.     found = false
  521.     WHILE NOT found AND curr <> null
  522.       IF NodesMatch(theNode,curr) THEN 
  523.         found = true
  524.       ELSE
  525.         prev = curr
  526.         curr = curr->nextNode
  527.       END IF
  528.     WEND
  529.  
  530.     '..Remove node from list.
  531.     IF found THEN 
  532.       IF curr->kind >= buttonGadget AND curr->kind <= potYGadget THEN --gadCount
  533.       prev->nextNode = curr->nextNode
  534.     END IF
  535.   END IF
  536. END SUB
  537.  
  538. SUB RedrawGUIObjects
  539. SHARED guiObjList
  540. DECLARE STRUCT GUIObjType *curr
  541.   IF guiObjList = null THEN
  542.     MsgBox "GUI Object List is not initialised!","Continue"
  543.   ELSE
  544.     '..Traverse the list drawing objects in requester window.
  545.     curr = guiObjList->nextNode
  546.     WHILE curr <> null
  547.       objKind = curr->kind
  548.       IF objKind = staticText THEN
  549.     '..Text.
  550.     DrawTextLayoutGuide(curr->x1,curr->y1,curr->x2,curr->y2)
  551.       ELSE
  552.     '..Gadget or Bevel-Box.
  553.         CASE
  554.           objKind = buttonGadget     : boxStyle = RAISED
  555.           objKind = stringGadget     : boxStyle = STRGAD
  556.           objKind = longintGadget    : boxStyle = STRGAD
  557.           objKind = potXGadget       : boxStyle = RAISED
  558.           objKind = potYGadget       : boxStyle = RAISED
  559.       objKind = raisedBevelBox   : boxStyle = RAISED
  560.       objKind = recessedBevelBox : boxStyle = RECESSED
  561.         END CASE
  562.  
  563.     BEVELBOX (curr->x1,curr->y1)-(curr->x2,curr->y2),boxStyle
  564.       END IF
  565.  
  566.       curr = curr->nextNode
  567.     WEND
  568.   END IF
  569. END SUB
  570.  
  571. SUB SaveGUIObjects(SHORTINT fileNum)
  572. SHARED guiObjList
  573. DECLARE STRUCT GUIObjType *curr
  574.   IF guiObjList = null THEN
  575.     MsgBox "GUI Object List is not initialised!","Continue"
  576.   ELSE
  577.     '..Traverse the list writing objects to a file.   
  578.     curr = guiObjList->nextNode
  579.     WHILE curr <> null
  580.       WRITE #fileNum,curr->kind
  581.       IF curr->kind = potXGadget OR curr->kind = potYGadget THEN
  582.     WRITE #fileNum,curr->potVal
  583.       ELSE
  584.     IF curr->kind <> raisedBevelBox AND curr->kind <> recessedBevelBox THEN
  585.       WRITE #fileNum,CSTR(curr->theText)
  586.     END IF
  587.       END IF
  588.       IF curr->kind = staticText THEN
  589.     WRITE #fileNum,CSTR(curr->fontName)
  590.     WRITE #fileNum,curr->fontHeight
  591.     WRITE #fileNum,curr->textStyle
  592.     WRITE #fileNum,curr->frontColor
  593.     WRITE #fileNum,curr->backColor
  594.       END IF
  595.       WRITE #fileNum,curr->x1,curr->y1,curr->x2,curr->y2
  596.       curr = curr->nextNode
  597.     WEND
  598.   END IF
  599. END SUB
  600.  
  601. SUB GetGUIObjects(SHORTINT fileNum)
  602. SHARED guiObjList, gadCount
  603. DECLARE STRUCT GUIObjType *curr
  604. SHORTINT x1,y1,x2,y2
  605.   IF guiObjList = null THEN
  606.     MsgBox "GUI Object List is not initialised!","Continue"
  607.   ELSE
  608.     '..Read objects from a file adding them to the list.
  609.     gadCount = 0
  610.     curr = guiObjList
  611.     WHILE NOT EOF(fileNum)
  612.       curr->nextNode = NewGUIObj
  613.       curr = curr->nextNode
  614.       IF curr = null THEN MsgBox "Memory allocation error!","Continue":EXIT SUB
  615.       INPUT #fileNum,theVal : curr->kind = theVal
  616.       IF curr->kind <> staticText AND curr->kind <> raisedBevelBox AND ~
  617.      curr->kind <> recessedBevelBox THEN ++gadCount
  618.       IF curr->kind = potXGadget OR curr->kind = potYGadget THEN
  619.     INPUT #fileNum,theVal : curr->potVal = theVal
  620.       ELSE
  621.     IF curr->kind <> raisedBevelBox AND curr->kind <> recessedBevelBox THEN
  622.       INPUT #fileNum,theVal$
  623.           curr->theText = ALLOC(LEN(theVal$)+1)
  624.           IF curr->theText = null THEN MsgBox "Memory allocation error!","Continue":EXIT SUB
  625.           STRING theText ADDRESS curr->theText
  626.           theText = theVal$
  627.     END IF
  628.       END IF
  629.       IF curr->kind = staticText THEN
  630.     INPUT #fileNum,theVal$
  631.         curr->fontName = ALLOC(LEN(theVal$)+1)
  632.         IF curr->fontName = null THEN MsgBox "Memory allocation error!","Continue":EXIT SUB
  633.         STRING fontName ADDRESS curr->fontName
  634.         fontName = theVal$
  635.     INPUT #fileNum,theVal : curr->fontHeight = theVal
  636.     INPUT #fileNum,theVal : curr->textStyle = theVal
  637.     INPUT #fileNum,theVal : curr->frontColor = theVal
  638.     INPUT #fileNum,theVal : curr->backColor = theVal
  639.       END IF 
  640.       INPUT #fileNum,x1,y1,x2,y2
  641.       curr->x1 = x1 : curr->y1 = y1 : curr->x2 = x2 : curr->y2 = y2
  642.     WEND
  643.   END IF
  644. END SUB
  645.  
  646. SUB SHORTINT RenderGUIObjects(SHORTINT fileNum)
  647. SHARED guiObjList
  648. DECLARE STRUCT GUIObjType *curr
  649. LONGINT theGadNum
  650. SHORTINT x1,y1, x2,y2
  651. SHORTINT bevelBoxMode
  652.   IF guiObjList = null THEN
  653.     MsgBox "GUI Object List is not initialised!","Continue"
  654.     '..No minimum gadget number.
  655.     RenderGUIObjects = 0
  656.   ELSE
  657.     '..Traverse the list generating code to render objects.
  658.     theGadNum = 256
  659.     curr = guiObjList->nextNode
  660.     WHILE curr <> null
  661.       IF curr->kind = staticText THEN
  662.     '..Text.
  663.     PRINT #fileNum,"  FONT ";CHR$(34);CSTR(curr->fontName);CHR$(34);","; ~
  664.                    LTRIM$(STR$(curr->fontHeight));" : ";
  665.     PRINT #fileNum,"STYLE";curr->textStyle;" : ";
  666.     PRINT #fileNum,"COLOR";STR$(curr->frontColor);","; ~
  667.             LTRIM$(STR$(curr->backColor));" : ";
  668.         PRINT #fileNum,"PENUP";" : ";
  669.     IF CSTR(curr->theText) <> "" THEN
  670.       PRINT #fileNum,"SETXY";STR$(curr->x1);",";LTRIM$(STR$(curr->y2))
  671.       PRINT #fileNum,"  PRINT ";CHR$(34);CSTR(curr->theText);CHR$(34);";"
  672.     END IF
  673.       ELSE
  674.     objKind = curr->kind
  675.        IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN
  676.       '..Bevel-Box.
  677.       PRINT #fileNum,"  BEVELBOX ";Rect(curr->x1,curr->y1,curr->x2,curr->y2);",";
  678.       IF objKind = raisedBevelBox THEN 
  679.         bevelBoxMode = RAISED 
  680.       ELSE
  681.         bevelBoxMode = RECESSED
  682.       END IF
  683.       PRINT #fileNum,LTRIM$(STR$(bevelBoxMode))
  684.     ELSE
  685.       '..Gadget.
  686.       x1 = curr->x1 : y1 = curr->y1
  687.       x2 = curr->x2 : y2 = curr->y2
  688.       
  689.           objKind = curr->kind
  690.         
  691.       '..Are offsets required for this gadget?
  692.       IF objKind = buttonGadget THEN
  693.         ++x2
  694.         ++y2
  695.       ELSE
  696.         IF objKind = stringGadget OR objKind = longintGadget THEN
  697.           x1 = x1+6 : y1 = y1+3
  698.           x2 = x2+6 : y2 = y2+3
  699.         END IF
  700.       END IF
  701.  
  702.           --theGadNum
  703.  
  704.        PRINT #fileNum,"  GADGET";STR$(theGadNum);",ON,";
  705.       IF curr->kind <> potXGadget AND curr->kind <> potYGadget THEN
  706.         PRINT #fileNum,CHR$(34);
  707.         IF CSTR(curr->theText) <> "" THEN PRINT #fileNum,CSTR(curr->theText);
  708.           PRINT #fileNum,CHR$(34);",";
  709.         ELSE
  710.           PRINT #fileNum,LTRIM$(STR$(curr->potVal));",";
  711.       END IF
  712.       PRINT #fileNum,Rect(x1,y1,x2,y2);",";
  713.           CASE
  714.             curr->kind = buttonGadget  : PRINT #fileNum,"BUTTON"
  715.             curr->kind = stringGadget  : PRINT #fileNum,"STRING"
  716.             curr->kind = longintGadget : PRINT #fileNum,"LONGINT"
  717.             curr->kind = potXGadget    : PRINT #fileNum,"POTX"
  718.             curr->kind = potYGadget    : PRINT #fileNum,"POTY"
  719.           END CASE
  720.     END IF
  721.       END IF
  722.       curr = curr->nextNode
  723.     WEND
  724.     '..Return minimum gadget number or zero if no gadgets.
  725.     IF theGadNum <> 256 THEN RenderGUIObjects = theGadNum ELSE RenderGUIObjects = 0
  726.   END IF
  727. END SUB
  728.  
  729. {* GUI object modification SUBs *}
  730.  
  731. SUB ADDRESS InsideGUIObj(SHORTINT x, SHORTINT y)
  732. SHARED guiObjList
  733. DECLARE STRUCT GUIObjType *curr
  734. LONGINT withinBounds
  735.   IF guiObjList = null THEN
  736.     MsgBox "GUI Object List is not initialised!","Continue"
  737.     InsideGUIObj = null
  738.   ELSE
  739.     '..Find node.
  740.     curr = guiObjList->nextNode
  741.     withinBounds = false
  742.     WHILE NOT withinBounds AND curr <> null
  743.       IF x > curr->x1+EDGE_THICKNESS AND x < curr->x2-EDGE_THICKNESS AND ~ 
  744.      y > curr->y1+EDGE_THICKNESS AND y < curr->y2-EDGE_THICKNESS THEN
  745.         withinBounds = true
  746.       ELSE
  747.         curr = curr->nextNode
  748.       END IF
  749.     WEND
  750.  
  751.     '..Return address of node (or null).
  752.     IF withinBounds THEN InsideGUIObj = curr ELSE InsideGUIObj = null
  753.   END IF
  754. END SUB
  755.  
  756. SUB SelectGUIObj(ADDRESS theObject)
  757. SHARED wdwID
  758. DECLARE STRUCT GUIObjType *guiObject
  759. SHORTINT left, right, top, bottom
  760.   guiObject = theObject
  761.   left = guiObject->x1 : top = guiObject->y1
  762.   right = guiObject->x2 : bottom = guiObject->y2
  763.   WINDOW OUTPUT wdwID
  764.   COLOR 3:PENUP:SETXY left,top:PENDOWN
  765.   SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  766. END SUB
  767.  
  768. SUB DeleteGUIObj(ADDRESS theObject)
  769. SHARED wdwID, dirty
  770. DECLARE STRUCT GUIObjType *guiObject
  771. STRING objName SIZE 20
  772.   guiObject = theObject
  773.   objKind = guiObject->kind
  774.   CASE
  775.     objKind = buttonGadget     : objName = "button"  
  776.     objKind = stringGadget     : objName = "string gadget"
  777.     objKind = longintGadget    : objName = "longint gadget"  
  778.     objKind = potXGadget       : objName = "horizontal slider"  
  779.     objKind = potYGadget       : objName = "vertical slider"  
  780.     objKind = staticText       : objName = "static text"
  781.     objKind = raisedBevelBox   : objName = "plateau"
  782.     objKind = recessedBevelBox : objName = "panel"
  783.   END CASE
  784.   IF MsgBox("Delete selected "+objName+"?","Yes","No") THEN 
  785.     RemoveGUIObj(theObject)
  786.     IF NOT dirty THEN dirty = true
  787.   END IF
  788.   '..Refresh display to get rid of selection box and
  789.   '..possibly to reflect absence of deleted object.
  790.   WINDOW OUTPUT wdwID
  791.   CLS : RedrawGUIObjects
  792. END SUB
  793.  
  794. SUB ModifyGUIObjVal(ADDRESS theObject)
  795. SHARED dirty, wdwID
  796. DECLARE STRUCT GUIObjType *guiObject, tmpObject
  797. STRING objName SIZE 20
  798. STRING prompt SIZE 30
  799.  
  800.   guiObject = theObject
  801.  
  802.   objKind = guiObject->kind
  803.  
  804.   '..Can't modify Bevel-Box since it holds no text value!
  805.   IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN 
  806.     MsgBox "No text to modify.","Continue"
  807.     '..Refresh display to get rid of selection box.
  808.     WINDOW OUTPUT wdwID
  809.     CLS : RedrawGUIObjects
  810.     EXIT SUB
  811.   END IF
  812.  
  813.   CASE
  814.    objKind = buttonGadget : objName="button" : prompt = "Enter Button Text"
  815.    objKind = stringGadget : objName="string gadget" : prompt = "Enter Default Text"
  816.    objKind = longintGadget : objName="longint gadget" : prompt = "Enter Default Value"  
  817.    objKind = potXGadget : objName="horizontal slider":prompt = "Enter Maximum Slider Value"
  818.    objKind = potYGadget : objName="vertical slider":prompt = "Enter Maximum Slider Value" 
  819.    objKind = staticText : objName="static text":prompt = "Enter Static Text"  
  820.   END CASE
  821.  
  822.   '..Store current values.
  823.   IF objKind <> potXGadget AND objKind <> potYGadget THEN 
  824.     tmpObject->theText = guiObject->theText
  825.   END IF
  826.  
  827.   IF objKind = staticText THEN
  828.     tmpObject->fontName = guiObject->fontName
  829.     tmpObject->fontHeight = guiObject->fontHeight
  830.     tmpObject->textStyle = guiObject->textStyle
  831.     tmpObject->frontColor = guiObject->frontColor
  832.     tmpObject->backColor = guiObject->backColor
  833.   END IF
  834.  
  835.   IF objKind = potXGadget OR objKind = potYGadget THEN
  836.     tmpObject->potVal = guiObject->potVal
  837.   END IF
  838.  
  839.   '..Change the GUI object?
  840.   IF MsgBox("Modify selected "+objName+"?","Yes","No") THEN 
  841.     IF GUIObjVal(theObject, prompt) <> null THEN 
  842.       '..Valid change made.     
  843.       IF NOT dirty THEN dirty = true
  844.     ELSE
  845.       '..Invalid value(s) entered, so restore old values.
  846.       IF objKind <> potXGadget AND objKind <> potYGadget THEN 
  847.          guiObject->theText = tmpObject->theText
  848.       END IF
  849.  
  850.       IF objKind = staticText THEN
  851.         guiObject->fontName = tmpObject->fontName
  852.         guiObject->fontHeight = tmpObject->fontHeight
  853.         guiObject->textStyle = tmpObject->textStyle
  854.         guiObject->frontColor = tmpObject->frontColor
  855.         guiObject->backColor = tmpObject->backColor
  856.       END IF
  857.  
  858.      IF objKind = potXGadget OR objKind = potYGadget THEN
  859.         guiObject->potVal = tmpObject->potVal
  860.      END IF
  861.     END IF
  862.   END IF
  863.   '..Refresh display to get rid of selection box.
  864.   WINDOW OUTPUT wdwID
  865.   CLS : RedrawGUIObjects
  866. END SUB
  867.  
  868. SUB MoveGUIObj(ADDRESS theObject)
  869. SHARED wdwID, dirty
  870. DECLARE STRUCT GUIObjType *guiObject
  871. ADDRESS RPort
  872. SHORTINT oldX1,oldY1, oldX2,oldY2
  873. SHORTINT x,y, lastX,lastY, xDiff,yDiff
  874. SHORTINT left, right, top, bottom
  875.  
  876.   guiObject = theObject
  877.  
  878.   '..Remove the object from the list.
  879.   RemoveGUIObj(guiObject)
  880.  
  881.   '..Refresh the display to show absence of the object.
  882.   WINDOW OUTPUT wdwID
  883.   CLS : RedrawGUIObjects
  884.   
  885.   '..Get initial position of object.
  886.   left = guiObject->x1 : top = guiObject->y1
  887.   right = guiObject->x2 : bottom = guiObject->y2
  888.  
  889.   oldX1 = left : oldY1 = top
  890.   oldX2 = right : oldY2 = bottom
  891.  
  892.   RPort = WINDOW(8)
  893.   SetDrMd(RPort,2)    '..XOR mode
  894.  
  895.   selected = true
  896.  
  897.   lastX = MOUSE(1) : lastY = MOUSE(2)
  898.   x = lastX : y = lastY
  899.  
  900.   '..Allow the object to be moved.
  901.   WHILE selected AND ~
  902.     lastX > left+EDGE_THICKNESS AND lastX < right-EDGE_THICKNESS AND ~
  903.     lastY > top+EDGE_THICKNESS AND lastY < bottom-EDGE_THICKNESS
  904.     IF MOUSE(0) THEN
  905.       '..Draw selection box.
  906.       COLOR 1:PENUP:SETXY left,top:PENDOWN
  907.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  908.  
  909.       ShowMouseCoordinates(left,top,right,bottom)
  910.  
  911.       '..Wait for mouse position to change or left button to be released.
  912.       WHILE selected AND x = lastX AND y = lastY
  913.         x = MOUSE(1) : y = MOUSE(2)
  914.         IF NOT MOUSE(0) THEN selected = false
  915.       WEND
  916.  
  917.       '..Erase selection box.
  918.       COLOR 0:PENUP:SETXY left,top:PENDOWN
  919.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  920.  
  921.       '..Adjust selection box? 
  922.       '..Treat horizontal and vertical motion independently.
  923.       xDiff = x-lastX : yDiff = y-lastY
  924.  
  925.       IF left+xDiff >= 0 THEN
  926.         left = left + xDiff : right = right + xDiff
  927.     lastX = x
  928.       ELSE
  929.     x = lastX
  930.       END IF
  931.  
  932.       IF top+yDiff >= 0 THEN
  933.         top = top + yDiff : bottom = bottom + yDiff 
  934.     lastY = y
  935.       ELSE
  936.     y = lastY
  937.       END IF
  938.     ELSE
  939.       '..Mouse button has been released.
  940.       selected = false
  941.     END IF 
  942.   WEND
  943.    
  944.   SetDrMd(RPort,1)    '..JAM2 mode
  945.   
  946.   '..Modify the object's position.
  947.   guiObject->x1 = left : guiObject->y1 = top
  948.   guiObject->x2 = right : guiObject->y2 = bottom
  949.  
  950.   '..Add the modified object to (the end of) the list.
  951.   guiObject->nextNode = null
  952.   AddGUIObj(guiObject)
  953.  
  954.   '..Refresh the display to show object's (new) position.
  955.   WINDOW OUTPUT wdwID
  956.   CLS : RedrawGUIObjects
  957.  
  958.   IF NOT dirty AND (left <> oldX1 OR right <> oldX2 OR ~
  959.           top <> oldY1 OR bottom <> oldY2) THEN dirty = true
  960.  
  961.   ResetReqWdwTitle
  962. END SUB
  963.  
  964. SUB SHORTINT ObjEdge(SHORTINT x, SHORTINT y, ADDRESS theObject)
  965. DECLARE STRUCT GUIObjType *guiObject
  966.   guiObject = theObject
  967.  
  968.   CASE
  969.     x >= guiObject->x1 AND x <= guiObject->x1+EDGE_THICKNESS AND ~
  970.     y >= guiObject->y1 AND y <= guiObject->y2 : ObjEdge = LEFT_EDGE
  971.  
  972.     x >= guiObject->x2-EDGE_THICKNESS AND x <= guiObject->x2 AND ~
  973.     y >= guiObject->y1 AND y <= guiObject->y2: ObjEdge = RIGHT_EDGE
  974.  
  975.     y >= guiObject->y1 AND y <= guiObject->y1+EDGE_THICKNESS AND ~
  976.     x >= guiObject->x1 AND x <= guiObject->x2 : ObjEdge = TOP_EDGE
  977.  
  978.     y >= guiObject->y2-EDGE_THICKNESS AND y <= guiObject->y2 AND ~
  979.     x >= guiObject->x1 AND x <= guiObject->x2: ObjEdge = BOTTOM_EDGE
  980.  
  981.     default : ObjEdge = NO_EDGE
  982.   END CASE
  983. END SUB
  984.  
  985. SUB ADDRESS OnGUIObjBorder(SHORTINT x, SHORTINT y, ADDRESS edge)
  986. SHARED guiObjList
  987. DECLARE STRUCT GUIObjType *curr
  988. LONGINT onBorder
  989.   IF guiObjList = null THEN
  990.     MsgBox "GUI Object List is not initialised!","Continue"
  991.     OnGUIObjBorder = null
  992.     *%edge := NO_EDGE
  993.   ELSE
  994.     '..Find node.
  995.     curr = guiObjList->nextNode
  996.     onBorder = false
  997.     WHILE NOT onBorder AND curr <> null
  998.       *%edge := ObjEdge(x,y,curr)
  999.       IF *%edge <> NO_EDGE THEN
  1000.     onBorder = true
  1001.       ELSE
  1002.         curr = curr->nextNode
  1003.       END IF
  1004.     WEND
  1005.  
  1006.     '..Return address of node (or null).
  1007.     IF onBorder THEN 
  1008.       OnGUIObjBorder = curr
  1009.     ELSE 
  1010.       *%edge := NO_EDGE
  1011.       OnGUIObjBorder = null
  1012.     END IF
  1013.   END IF
  1014. END SUB
  1015.  
  1016. SUB ResizeGUIObj(ADDRESS theObject, SHORTINT edge)
  1017. SHARED wdwID, dirty
  1018. DECLARE STRUCT GUIObjType *guiObject
  1019. ADDRESS RPort
  1020. SHORTINT oldX1,oldY1, oldX2,oldY2
  1021. SHORTINT x,y, lastX,lastY
  1022. SHORTINT left, right, top, bottom
  1023.  
  1024.   guiObject = theObject
  1025.  
  1026.   IF guiObject->kind = staticText THEN EXIT SUB
  1027.  
  1028.   '..Remove the object from the list.
  1029.   RemoveGUIObj(guiObject)
  1030.  
  1031.   '..Refresh the display to show absence of the object.
  1032.   WINDOW OUTPUT wdwID
  1033.   CLS : RedrawGUIObjects
  1034.   
  1035.   '..Get initial position of object.
  1036.   left = guiObject->x1 : top = guiObject->y1
  1037.   right = guiObject->x2 : bottom = guiObject->y2
  1038.  
  1039.   oldX1 = left : oldY1 = top
  1040.   oldX2 = right : oldY2 = bottom
  1041.  
  1042.   RPort = WINDOW(8)
  1043.   SetDrMd(RPort,2)    '..XOR mode
  1044.  
  1045.   selected = true
  1046.  
  1047.   lastX = MOUSE(1) : lastY = MOUSE(2)
  1048.   x = lastX : y = lastY
  1049.  
  1050.   '..Allow the object to be resized.
  1051.   WHILE selected
  1052.     IF MOUSE(0) THEN
  1053.       '..Draw selection box.
  1054.       COLOR 1:PENUP:SETXY left,top:PENDOWN
  1055.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  1056.  
  1057.       ShowMouseCoordinates(left,top,right,bottom)
  1058.  
  1059.       '..Wait for mouse position to change or left button to be released.
  1060.       WHILE selected AND x = lastX AND y = lastY
  1061.         x = MOUSE(1) : y = MOUSE(2)
  1062.         IF NOT MOUSE(0) THEN selected = false
  1063.       WEND
  1064.  
  1065.       '..Erase selection box.
  1066.       COLOR 0:PENUP:SETXY left,top:PENDOWN
  1067.       SETXY right,top:SETXY right,bottom:SETXY left,bottom:SETXY left,top
  1068.  
  1069.       '..Adjust one edge of the selection box?
  1070.       IF x >= 0 AND y >= 0 THEN
  1071.     '..Yes.
  1072.         CASE
  1073.       edge = LEFT_EDGE   : IF x < right-EDGE_THICKNESS THEN left = x
  1074.       edge = RIGHT_EDGE  : IF x > left+EDGE_THICKNESS THEN right = x
  1075.       edge = TOP_EDGE    : IF y < bottom-EDGE_THICKNESS THEN top = y
  1076.       edge = BOTTOM_EDGE : IF y > top+EDGE_THICKNESS THEN bottom = y
  1077.         END CASE     
  1078.         lastX = x : lastY = y
  1079.       ELSE
  1080.     '..No. Retain previous edge position.
  1081.     x = lastX : y = lastY
  1082.       END IF
  1083.     ELSE
  1084.       '..Mouse button has been released.
  1085.       selected = false
  1086.     END IF 
  1087.   WEND
  1088.    
  1089.   SetDrMd(RPort,1)    '..JAM2 mode
  1090.   
  1091.   '..Modify the object's position.
  1092.   guiObject->x1 = left : guiObject->y1 = top
  1093.   guiObject->x2 = right : guiObject->y2 = bottom
  1094.  
  1095.   '..Add the modified object to (the end of) the list.
  1096.   guiObject->nextNode = null
  1097.   AddGUIObj(guiObject)
  1098.  
  1099.   '..Refresh the display to show object's (new) position.
  1100.   WINDOW OUTPUT wdwID
  1101.   CLS : RedrawGUIObjects
  1102.  
  1103.   IF NOT dirty AND (left <> oldX1 OR right <> oldX2 OR ~
  1104.           top <> oldY1 OR bottom <> oldY2) THEN dirty = true
  1105.  
  1106.   ResetReqWdwTitle
  1107. END SUB
  1108.  
  1109. {* Project menu SUBs *}
  1110.  
  1111. SUB ToggleToolBar
  1112. SHARED toolBarActive, wdwID, buttonText
  1113. SHORTINT fontWidth, fontHeight, n
  1114.  
  1115.   IF NOT toolBarActive THEN
  1116.     '..Activate Tool Bar.
  1117.     fontWidth = SCREEN(5)
  1118.     fontHeight = SCREEN(6)
  1119.     WINDOW toolWdw,,(10,10)-(10+11*fontWidth,10+19.5*fontHeight),10
  1120.     FOR n=gButton TO gRecessedBox
  1121.       '..Render tool bar buttons making each one as wide as necessary
  1122.       '..to accomodate the longest button text.
  1123.       GADGET n,ON,buttonText(n-gButton+1),(fontWidth,fontHeight+(n-1)*2*fontHeight)- ~
  1124.                 (fontWidth+8*fontWidth,fontHeight+n*2*fontHeight),BUTTON,1
  1125.     NEXT
  1126.  
  1127.     WINDOW OUTPUT wdwID
  1128.     MENU mProject,iToolBar,sCheck
  1129.     toolBarActive = true
  1130.   ELSE
  1131.     '..Deactivate Tool Bar.
  1132.     FOR n=gButton TO gRecessedBox
  1133.       GADGET CLOSE n
  1134.     NEXT
  1135.     WINDOW OUTPUT toolWdw    '..prevent main window menus from being cleared.
  1136.     WINDOW CLOSE toolWdw
  1137.     WINDOW OUTPUT wdwID
  1138.     MENU mProject,iToolBar,sEnable
  1139.     toolBarActive = false
  1140.   END IF
  1141. END SUB
  1142.  
  1143. SUB SetProjectName(STRING fileReqTitle)
  1144. SHARED projectName
  1145. STRING newProjectName SIZE 80
  1146.   newProjectName = FileBox$(fileReqTitle)
  1147.   IF newProjectName <> "" THEN projectName = newProjectName
  1148. END SUB
  1149.  
  1150. SUB StoreInfo
  1151. SHARED projectName, reqName
  1152. SHARED wdwID, wdwTitle, wdwFlags
  1153. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1154.   OPEN "O",#1,projectName+".req"
  1155.   IF HANDLE(1) = null THEN 
  1156.     MsgBox "Unable to open "+projectName+".req for writing.","Continue"
  1157.     EXIT SUB
  1158.   ELSE
  1159.     PRINT #1,"#REQED PROJECT#"
  1160.     PRINT #1,reqName
  1161.     WRITE #1,wdwID
  1162.     IF wdwTitle <> "" THEN PRINT #1,wdwTitle ELSE PRINT #1,"#NULL#"
  1163.     WRITE #1,wdwFlags
  1164.     WRITE #1,wdw_x1,wdw_y1,wdw_x2,wdw_y2
  1165.     SaveGUIObjects(1)
  1166.     CLOSE #1
  1167.   END IF
  1168. END SUB
  1169.  
  1170. SUB GenerateCode
  1171. SHARED projectName, reqName, wdwID, wdwTitle, wdwFlags
  1172. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1173. STRING theTitle SIZE 80
  1174. SHORTINT minGadget
  1175.   IF reqName = "" THEN
  1176.     reqName = InputBox$("Requester SUB name?","Set requester SUB name",reqName,170,10)
  1177.   END IF
  1178.  
  1179.   IF reqName = "" THEN
  1180.     MsgBox projectName+".b not created.","Continue"
  1181.     EXIT SUB
  1182.   END IF
  1183.   OPEN "O",#1,projectName+".b"  
  1184.   IF HANDLE(1) = null THEN 
  1185.     MsgBox "Unable to open "+projectName+".b for writing.","Continue"
  1186.     EXIT SUB
  1187.   ELSE
  1188.     PRINT #1,"SUB ";reqName  
  1189.     {* Variables *}
  1190.     PRINT #1,"SHORTINT theGadget, n"  
  1191.     {* Code for window *}
  1192.     PRINT #1,"  WINDOW";STR$(wdwID);",";
  1193.     IF wdwTitle <> "" THEN
  1194.       '..A title has been specified. 
  1195.       PRINT #1,CHR$(34);wdwTitle;CHR$(34);
  1196.     ELSE
  1197.       '..There's no title but the window is moveable
  1198.       '..(otherwise we want no title bar at all).
  1199.       IF wdwFlags AND 2 THEN PRINT #1,CHR$(34);CHR$(34);
  1200.     END IF
  1201.     PRINT #1,",";Rect(wdw_x1,wdw_y1,wdw_x2,wdw_y2);",";LTRIM$(STR$(wdwFlags))
  1202.     {* Render gadgets, bevel-boxes and text *}
  1203.     PRINT #1,"  ";CHR$(123);"* RENDER GADGETS, BEVEL-BOXES AND TEXT *";CHR$(125)
  1204.     minGadget = RenderGUIObjects(1)
  1205.     {* Await and handle gadget activity *}
  1206.     PRINT #1,"  ";CHR$(123);"* GADGET HANDLING CODE STARTS HERE *";CHR$(125)
  1207.     PRINT #1,"  GADGET WAIT 0"
  1208.     PRINT #1,"  theGadget = GADGET(1)"
  1209.     {* Cleanup code *}
  1210.     PRINT #1,"  ";CHR$(123);"* CLEAN UP *";CHR$(125)
  1211.     IF minGadget <> 0 THEN
  1212.       PRINT #1,"  FOR n=255 TO";minGadget;"STEP -1"
  1213.       PRINT #1,"    GADGET CLOSE n"
  1214.       PRINT #1,"  NEXT" 
  1215.     END IF
  1216.     PRINT #1,"  WINDOW CLOSE";wdwID
  1217.     PRINT #1,"END SUB"
  1218.   END IF
  1219.   CLOSE #1
  1220. END SUB
  1221.  
  1222. SUB SaveProject
  1223. SHARED dirty, projectName, reqName
  1224.   SetWdwRect
  1225.   IF dirty THEN
  1226.     IF projectName = "" THEN CALL SetProjectName("Save Project")
  1227.     IF projectName = "" THEN
  1228.       '..Abort.
  1229.       MsgBox "Project name not specified.","Continue"
  1230.     ELSE
  1231.       GenerateCode
  1232.       IF reqName <> "" THEN
  1233.     '..Abort.
  1234.         StoreInfo
  1235.         dirty = false
  1236.       END IF
  1237.     END IF
  1238.   END IF
  1239. END SUB
  1240.  
  1241. SUB SaveAs
  1242. SHARED projectName, reqName, dirty
  1243. STRING oldProjectName SIZE 80
  1244. STRING oldReqName SIZE 80
  1245.   oldProjectName = projectName
  1246.   projectName = ""
  1247.   SetProjectName("Save As...")
  1248.   IF projectName = "" THEN
  1249.     '..Abort.
  1250.     MsgBox "Name not specified.","Continue"
  1251.     projectName = oldProjectName
  1252.   ELSE
  1253.     SetWdwRect
  1254.     oldReqName = reqName
  1255.     reqName = ""
  1256.     GenerateCode
  1257.     IF reqName = "" THEN
  1258.       '..Abort.
  1259.       reqName = oldReqName
  1260.       projectName = oldProjectName
  1261.     ELSE
  1262.       StoreInfo
  1263.       IF dirty THEN dirty = false
  1264.     END IF
  1265.   END IF
  1266. END SUB
  1267.  
  1268. SUB CloseProject
  1269. SHARED wdwID
  1270.   MENU CLEAR
  1271.   WINDOW CLOSE wdwID
  1272. END SUB
  1273.  
  1274. SUB OpenProject
  1275. SHARED projectName, reqName, dirty
  1276. SHARED wdwID, wdwTitle, wdwFlags
  1277. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1278. SHARED old_wdw_x1, old_wdw_y1
  1279. STRING oldProjectName SIZE 80
  1280. STRING fileType SIZE 80
  1281. STRING theName SIZE 80
  1282.  
  1283.   IF dirty THEN
  1284.     IF projectName <> "" THEN theName = projectName ELSE theName = "project"
  1285.     IF MsgBox("Save "+theName+"?","Yes","No") THEN CALL SaveProject
  1286.   END IF
  1287.  
  1288.   oldProjectName = projectName
  1289.   SetProjectName("Open Project")
  1290.  
  1291.   IF projectName = "" THEN
  1292.     MsgBox "Project name not specified.","Continue"
  1293.     projectName = oldProjectName
  1294.     EXIT SUB
  1295.   END IF 
  1296.  
  1297.   IF INSTR(projectName,".req") = 0 THEN
  1298.     MsgBox projectName+" not of required type.","Continue"
  1299.     projectName = oldProjectName
  1300.     EXIT SUB
  1301.   END IF
  1302.  
  1303.   IF GUIObjListHead = null THEN
  1304.     projectName = oldProjectName
  1305.     EXIT SUB
  1306.   END IF
  1307.  
  1308.   OPEN "I",#1,projectName
  1309.   IF HANDLE(1) = null THEN
  1310.     MsgBox "Unable to open "+projectName+" for input.","Continue"
  1311.     projectName = oldProjectName
  1312.     EXIT SUB
  1313.   ELSE
  1314.     LINE INPUT #1,fileType
  1315.     IF fileType <> "#REQED PROJECT#" THEN
  1316.       MsgBox projectName+" not of required type.","Continue"
  1317.       projectName = oldProjectName
  1318.       CLOSE #1
  1319.       EXIT SUB
  1320.     END IF
  1321.     CloseProject
  1322.     LINE INPUT #1,reqName
  1323.     INPUT #1,wdwID
  1324.     LINE INPUT #1,wdwTitle : IF wdwTitle = "#NULL#" THEN wdwTitle = ""
  1325.     INPUT #1,wdwFlags
  1326.     INPUT #1,wdw_x1,wdw_y1,wdw_x2,wdw_y2
  1327.     old_wdw_x1 = wdw_x1 : old_wdw_y1 = wdw_y1
  1328.     GetGUIObjects(1)
  1329.     CLOSE #1
  1330.     projectName = LEFT$(projectName,INSTR(projectName,".req")-1)
  1331.   END IF
  1332.   CreateWindow
  1333.   SetupMenus  
  1334.   dirty = false
  1335. END SUB
  1336.  
  1337. SUB NewProject
  1338. SHARED dirty, wdwID, wdwTitle, gadCount
  1339. SHARED wdwFlags, projectName, reqName
  1340. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1341. SHARED old_wdw_x1, old_wdw_y1
  1342. STRING theName SIZE 80
  1343.   IF dirty THEN
  1344.     IF projectName <> "" THEN theName = projectName ELSE theName = "project"
  1345.     IF MsgBox("Save "+theName+"?","Yes","No") THEN CALL SaveProject
  1346.   END IF
  1347.   CloseProject
  1348.   IF GUIObjListHead = null THEN EXIT SUB
  1349.   wdwID = 9
  1350.   wdwFlags = 0
  1351.   wdwTitle = ""
  1352.   reqName = ""
  1353.   projectName = ""
  1354.   wdw_x1 = 170 : wdw_y1 = 50 : old_wdw_x1 = 0 : old_wdw_y1 = 0
  1355.   wdw_x2 = 470 : wdw_y2 = 175
  1356.   gadCount = 0
  1357.   CreateWindow
  1358.   SetUpMenus  
  1359.   dirty = false
  1360. END SUB
  1361.  
  1362. SUB QuitProgram
  1363. SHARED finished, dirty, projectName
  1364. STRING theName SIZE 80
  1365.   IF dirty THEN
  1366.     IF projectName <> "" THEN theName = projectName ELSE theName = "project"
  1367.     IF MsgBox("Save "+theName+"?","Yes","No") THEN CALL SaveProject
  1368.   END IF
  1369.   finished = true
  1370. END SUB
  1371.  
  1372. {* Window menu SUBs *}
  1373.  
  1374. SUB PreviewRequester
  1375. SHARED wdwID, wdwFlags, wdwTitle
  1376. SHARED wdw_x1, wdw_y1, wdw_x2, wdw_y2
  1377. SHARED guiObjList
  1378. DECLARE STRUCT GUIObjType *curr
  1379. SHORTINT x1,y1, x2,y2
  1380. SHORTINT ID
  1381. SHORTINT objKind
  1382. LONGINT theGadNum
  1383. SHORTINT bevelBoxMode
  1384.  
  1385.   '..Render the window.
  1386.   SetWdwRect
  1387.   ID = wdwID-1
  1388.   IF ID = toolWdw THEN ID = 9  '..wrap around?
  1389.   IF wdwFlags AND 2 THEN
  1390.     '..Moveable, so need a title bar.
  1391.     WINDOW ID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  1392.   ELSE
  1393.     IF wdwTitle <> "" THEN
  1394.       '..A title has been specified.
  1395.       WINDOW ID,wdwTitle,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  1396.     ELSE
  1397.       '..No title specified.
  1398.       WINDOW ID,,(wdw_x1,wdw_y1)-(wdw_x2,wdw_y2),wdwFlags
  1399.     END IF
  1400.   END IF
  1401.  
  1402.   '..Set up menu.
  1403.   MENU mProject,iProject,sEnable,    "Project"
  1404.   MENU mProject,iExit,sEnable,        "Exit", "E"
  1405.  
  1406.   '..Render gadgets and text.
  1407.   IF guiObjList = null THEN
  1408.     MsgBox "GUI Object List is not initialised!","Continue"
  1409.   ELSE
  1410.     '..Traverse the list rendering objects.
  1411.     theGadNum = 256
  1412.     curr = guiObjList->nextNode
  1413.     WHILE curr <> null
  1414.       IF curr->kind = staticText THEN
  1415.     '..Text.
  1416.     FONT CSTR(curr->fontName),curr->fontHeight
  1417.     STYLE curr->textStyle
  1418.     COLOR curr->frontColor,curr->backColor
  1419.         PENUP
  1420.     IF curr->theText <> null THEN
  1421.       SETXY curr->x1,curr->y2
  1422.       PRINT CSTR(curr->theText);
  1423.         END IF    
  1424.       ELSE
  1425.     objKind = curr->kind
  1426.     IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN
  1427.       '..Bevel-Box.
  1428.       IF objKind = raisedBevelBox THEN 
  1429.         bevelBoxMode = RAISED 
  1430.       ELSE
  1431.         bevelBoxMode = RECESSED
  1432.       END IF
  1433.       BEVELBOX (curr->x1,curr->y1)-(curr->x2,curr->y2),bevelBoxMode
  1434.     ELSE
  1435.       '..Gadget.
  1436.       x1 = curr->x1 : y1 = curr->y1
  1437.       x2 = curr->x2 : y2 = curr->y2
  1438.       
  1439.           objKind = curr->kind
  1440.         
  1441.       '..Are offsets required for this gadget?
  1442.       IF objKind = buttonGadget THEN
  1443.         ++x2
  1444.         ++y2
  1445.       ELSE
  1446.         IF objKind = stringGadget OR objKind = longintGadget THEN
  1447.           x1 = x1+6 : y1 = y1+3
  1448.           x2 = x2+6 : y2 = y2+3
  1449.         END IF
  1450.       END IF
  1451.  
  1452.           --theGadNum     
  1453.  
  1454.       IF curr->kind <> potXGadget AND curr->kind <> potYGadget THEN
  1455.          GADGET theGadNum,ON,CSTR(curr->theText),(x1,y1)-(x2,y2),objKind
  1456.       ELSE
  1457.          GADGET theGadNum,ON,curr->potVal,(x1,y1)-(x2,y2),objKind
  1458.       END IF
  1459.         END IF
  1460.       END IF
  1461.       curr = curr->nextNode
  1462.     WEND
  1463.     
  1464.     '..Await Exit item selection from Project menu or close-gadget click.
  1465.     REPEAT
  1466.       MENU WAIT
  1467.     UNTIL (MENU(0) = mProject AND MENU(1) = iExit) OR GADGET(1) = 256
  1468.  
  1469.     '..Clean up.    
  1470.     FOR n=255 TO theGadNum STEP -1
  1471.       GADGET CLOSE n
  1472.     NEXT
  1473.     WINDOW CLOSE ID
  1474.   END IF  
  1475. END SUB
  1476.  
  1477. SUB ToggleFlag(SHORTINT theItem)
  1478. SHARED wdwFlags
  1479. SHORTINT theFlag
  1480.   theFlag = CINT(2^(theItem-iSizeGadget))
  1481.   IF wdwFlags AND theFlag THEN 
  1482.     '..Set flag
  1483.     wdwFlags = wdwFlags - theFlag
  1484.   ELSE
  1485.     '..Reset flag
  1486.     wdwFlags = wdwFlags OR theFlag
  1487.   END IF
  1488. END SUB
  1489.  
  1490. SUB SetWdwID
  1491. SHARED wdwID, dirty
  1492. SHORTINT newID
  1493. STRING wdwIDStr SIZE 2
  1494.   wdwIDStr = STR$(wdwID)
  1495.   wdwIDStr = LTRIM$(wdwIDStr)
  1496.   newID = InputBox("New window ID (2..9)","Set window ID",wdwIDStr,170,10)
  1497.   IF newID <> wdwID AND newID >= 2 AND newID <= 9 THEN
  1498.     dirty = newID <> wdwID
  1499.     SetWdwRect
  1500.     CloseProject
  1501.     wdwID = newID
  1502.     CreateWindow
  1503.     SetUpMenus
  1504.   END IF
  1505. END SUB
  1506.  
  1507. SUB SetWdwTitle
  1508. SHARED wdwID, wdwTitle, dirty
  1509. STRING newTitle SIZE 100
  1510.   newTitle = InputBox$("New window Title?","Set window Title",wdwTitle,170,10)  
  1511.   IF newTitle <> wdwTitle THEN
  1512.     dirty = newTitle <> wdwTitle
  1513.     wdwTitle = newTitle
  1514.     SetWdwRect
  1515.     CloseProject
  1516.     CreateWindow
  1517.     SetUpMenus
  1518.   END IF
  1519. END SUB
  1520.  
  1521. SUB ModifyWindow(SHORTINT theItem)
  1522. SHARED dirty
  1523.   IF theItem >= iSizeGadget THEN 
  1524.     CALL ToggleFlag(theItem)
  1525.     IF NOT dirty THEN dirty = true
  1526.     SetWdwRect
  1527.     CloseProject
  1528.     CreateWindow
  1529.     SetUpMenus
  1530.   ELSE
  1531.     CASE 
  1532.       theItem = iSetID    : SetWdwID
  1533.       theItem = iSetTitle : SetWdwTitle
  1534.     END CASE
  1535.   END IF
  1536. END SUB
  1537.  
  1538. SUB DrawBox(SHORTINT objKind, ADDRESS theCoord)
  1539. SHARED wdwID
  1540. ADDRESS RPort
  1541. SHORTINT xDiff,yDiff, x,y, firstX,firstY
  1542. DECLARE STRUCT CoordType *coord
  1543.  
  1544.   coord = theCoord
  1545.  
  1546.   WINDOW OUTPUT wdwID
  1547.   RPort = WINDOW(8)
  1548.  
  1549.   '..Await a mouse click in the requester window.
  1550.   WHILE NOT MOUSE(0):SLEEP FOR .02:WEND
  1551.  
  1552.   '..Go no further if user didn't click in requester window.
  1553.   IF WINDOW(0) <> wdwID THEN
  1554.     coord->valid = false
  1555.     EXIT SUB 
  1556.   END IF
  1557.  
  1558.   firstX = MOUSE(1) : firstY = MOUSE(2)
  1559.  
  1560.   IF MOUSE(0) THEN
  1561.     SetDrMd(RPort,2)    '..XOR mode
  1562.  
  1563.     WHILE MOUSE(0)
  1564.       x = MOUSE(1) : y = MOUSE(2)
  1565.       xDiff = x-firstX : yDiff = y-firstY
  1566.       IF xDiff > 0 AND yDiff > 0 THEN 
  1567.      COLOR 1:PENUP:SETXY firstX,firstY:PENDOWN
  1568.     SETXY x,firstY:SETXY x,y:SETXY firstX,y:SETXY firstX,firstY
  1569.         ShowMouseCoordinates(firstX,firstY,x,y)
  1570.     COLOR 0:PENUP:SETXY firstX,firstY:PENDOWN
  1571.     SETXY x,firstY:SETXY x,y:SETXY firstX,y:SETXY firstX,firstY
  1572.       END IF
  1573.     WEND    
  1574.       
  1575.     SetDrMd(RPort,1)    '..JAM2 mode
  1576.  
  1577.     ResetReqWdwTitle
  1578.   
  1579.     IF xDiff > 0 AND yDiff > 0 THEN
  1580.       IF objKind = staticText THEN
  1581.     '..Text.
  1582.     DrawTextLayoutGuide(firstX,firstY,x,y)
  1583.     coord->valid = true   
  1584.       ELSE
  1585.     '..Gadget.
  1586.         CASE
  1587.           objKind = buttonGadget     : boxStyle = RAISED
  1588.           objKind = stringGadget     : boxStyle = STRGAD
  1589.           objKind = longintGadget    : boxStyle = STRGAD
  1590.           objKind = potXGadget       : boxStyle = RAISED
  1591.           objKind = potYGadget       : boxStyle = RAISED
  1592.       objKind = raisedBevelBox   : boxStyle = RAISED
  1593.       objKind = recessedBevelBox : boxStyle = RECESSED
  1594.         END CASE
  1595.  
  1596.      BEVELBOX (firstX,firstY)-(x,y),boxStyle
  1597.       coord->valid = true
  1598.       END IF
  1599.  
  1600.       '..Return coordinate info' for object.
  1601.       coord->x1 = firstX : coord->y1 = firstY
  1602.       coord->x2 = x : coord->y2 = y 
  1603.     ELSE
  1604.       coord->valid = false
  1605.     END IF
  1606.   ELSE
  1607.     coord->valid = false
  1608.   END IF
  1609. END SUB
  1610.  
  1611. SUB ADDRESS GUIObjVal(ADDRESS guiObjAddr, STRING prompt)
  1612. SHARED wdwID
  1613. DECLARE STRUCT GUIObjType *guiObj
  1614. DECLARE STRUCT FontInfo info
  1615. ADDRESS textAddress, RPort
  1616. SHORTINT objKind
  1617. STRING tmpString
  1618. STRING defaultString
  1619.  
  1620.   guiObj = guiObjAddr 
  1621.   objKind = guiObj->kind
  1622.  
  1623.   IF objKind <> potXGadget AND objKind <> potYGadget THEN
  1624.     IF guiObj->theText <> null THEN 
  1625.     defaultString = CSTR(guiObj->theText)
  1626.     ELSE
  1627.         defaultString = ""
  1628.     END IF
  1629.     IF objKind = longintGadget THEN
  1630.       '..Want to allow only entry of digits 0..9!
  1631.       textAddress = SADD(LTRIM$(STR$(InputBox(prompt,,defaultString,170,10))))
  1632.     ELSE
  1633.       textAddress = SADD(InputBox$(prompt,,defaultString,170,10))
  1634.     END IF
  1635.  
  1636.     guiObj->theText = ALLOC(LEN(CSTR(textAddress))+1)
  1637.     IF guiObj->theText = null THEN 
  1638.     MsgBox "Memory allocation error!","Continue"
  1639.     GUIObjVal = null
  1640.     ELSE
  1641.         STRING theText ADDRESS guiObj->theText
  1642.         theText = CSTR(textAddress)
  1643.         GUIObjVal = guiObj->theText
  1644.     END IF
  1645.  
  1646.     IF objKind = staticText THEN
  1647.       IF FontInfoRequest(info) THEN
  1648.     '..Okay -> use info' from requester.
  1649.     textAddress = info->fontName
  1650.     guiObj->fontHeight = info->fontHeight
  1651.     guiObj->textStyle = info->textStyle
  1652.     guiObj->frontColor = info->frontColor
  1653.     guiObj->backColor = info->backColor
  1654.       ELSE
  1655.     '..Use defaults.
  1656.         textAddress = SADD("topaz")
  1657.         guiObj->fontHeight = 8
  1658.         guiObj->textStyle = 0
  1659.         guiObj->frontColor = 1
  1660.         guiObj->backColor = 0
  1661.       END IF
  1662.  
  1663.       '..Copy the font name.
  1664.       guiObj->fontName = ALLOC(LEN(CSTR(textAddress))+1)
  1665.       IF guiObj->fontName = null THEN 
  1666.     MsgBox "Memory allocation error!","Continue"
  1667.     GUIObjVal = null
  1668.       ELSE
  1669.         STRING fontName ADDRESS guiObj->fontName
  1670.         fontName = CSTR(textAddress)
  1671.       END IF
  1672.  
  1673.       '..Adjust text selection box.
  1674.       guiObj->y1 = guiObj->y2 - guiObj->fontHeight
  1675.       WINDOW OUTPUT wdwID
  1676.       RPort = WINDOW(8)
  1677.       FONT CSTR(guiObj->fontName),guiObj->fontHeight
  1678.       IF CSTR(guiObj->theText) = "" THEN
  1679.     '..Make sure selection box is big enough to use!
  1680.     tmpString = "M"  '..use a wide character.
  1681.     length = 1
  1682.       ELSE
  1683.         tmpString = CSTR(guiObj->theText)
  1684.         length = LEN(tmpString)
  1685.       END IF
  1686.       guiObj->x2 = guiObj->x1 + TextLength(RPort,tmpString,length)
  1687.     END IF
  1688.   ELSE
  1689.     '..POTX or POTY.
  1690.     REPEAT
  1691.       IF guiObj->potVal > 0 THEN 
  1692.     defaultString = LTRIM$(STR$(guiObj->potVal))
  1693.       ELSE
  1694.     defaultString = ""
  1695.       END IF
  1696.       guiObj->potVal = InputBox(prompt,,defaultString,170,10)
  1697.     UNTIL guiObj->potVal > 0
  1698.     GUIObjVal = guiObj->potVal
  1699.   END IF
  1700. END SUB
  1701.  
  1702. SUB CreateGUIObj(SHORTINT objKind, SHORTINT boxStyle)
  1703. SHARED wdwID, dirty
  1704. DECLARE STRUCT CoordType coord
  1705. DECLARE STRUCT GUIObjType *guiObj
  1706. STRING prompt SIZE 30
  1707.  
  1708.   WINDOW OUTPUT toolWdw
  1709.   GADGET objKind,OFF
  1710.   WINDOW OUTPUT wdwID
  1711.    
  1712.   DrawBox(objKind, coord)
  1713.  
  1714.   IF coord->valid THEN
  1715.     guiObj = NewGUIObj
  1716.     guiObj->kind = objKind
  1717.     guiObj->x1 = coord->x1
  1718.     guiObj->y1 = coord->y1
  1719.     guiObj->x2 = coord->x2
  1720.     guiObj->y2 = coord->y2
  1721.  
  1722.     IF objKind = raisedBevelBox OR objKind = recessedBevelBox THEN
  1723.         '..Add bevel-box object to the list and set the "dirty" 
  1724.     '..flag since the layout has changed.
  1725.         AddGUIObj(guiObj)
  1726.         IF NOT dirty THEN dirty = true      
  1727.     ELSE
  1728.       CASE
  1729.         objKind = buttonGadget  : prompt = "Enter Button Text"
  1730.         objKind = stringGadget  : prompt = "Enter Default Text"
  1731.         objKind = longintGadget : prompt = "Enter Default Value" 
  1732.         objKind = potXGadget    : prompt = "Enter Maximum Slider Value (> 0)"
  1733.         objKind = potYGadget    : prompt = "Enter Maximum Slider Value (> 0)" 
  1734.         objKind = staticText    : prompt = "Enter Static Text"
  1735.       END CASE    
  1736.  
  1737.       IF GUIObjVal(guiObj, prompt) <> null THEN       
  1738.         '..The GUI object is valid so add it to the list
  1739.         '..and set the "dirty" flag since the layout has changed.
  1740.         AddGUIObj(guiObj)
  1741.         IF NOT dirty THEN dirty = true
  1742.  
  1743.         '..Redraw text layout guide now that we have font, style and color,
  1744.         '..having previously adjusted the selection box.
  1745.         IF objKind = staticText THEN
  1746.           WINDOW OUTPUT wdwID
  1747.           CLS : RedrawGUIObjects
  1748.         END IF
  1749.       END IF
  1750.     END IF
  1751.   END IF
  1752.   
  1753.   '..Restore gadget imagery in tool window.
  1754.   WINDOW OUTPUT toolWdw
  1755.   FOR n = gButton TO gRecessedBox : GADGET n,ON : NEXT
  1756.   WINDOW OUTPUT wdwID
  1757. END SUB
  1758.  
  1759. {*
  1760. ** Main.
  1761. *}
  1762. '..Initialise GUI object list.
  1763. IF GUIObjListHead = null THEN STOP
  1764.  
  1765. '..Initialise tool bar button text array.
  1766. InitToolBarButtonText
  1767.  
  1768. '..Initialise main window cross-hair mouse pointer.
  1769. InitCrossHairPointerData
  1770.  
  1771. '..Set up initial project.
  1772. wdwID = 9
  1773. wdw_x1 = 170 : wdw_y1 = 50 : old_wdw_x1 = wdw_x1 : old_wdw_y1 = wdw_y1
  1774. wdw_x2 = 470 : wdw_y2 = 175
  1775. gadCount = 0
  1776. toolBarActive = false : finished = false
  1777.  
  1778. CreateWindow
  1779. SetupMenus
  1780.  
  1781. '..Activate event trapping.
  1782. ON MENU GOSUB handle_menu : MENU ON
  1783. ON GADGET GOSUB handle_gadget : GADGET ON
  1784. ON WINDOW GOSUB handle_window : WINDOW ON
  1785. ON MOUSE GOSUB handle_mouse : MOUSE ON
  1786.  
  1787. '..Await events.
  1788. WHILE NOT finished
  1789.   SetCurrWdw
  1790.   SLEEP FOR .02
  1791. WEND
  1792.  
  1793. '..Deactivate event trapping.
  1794. MENU OFF : GADGET OFF : WINDOW OFF : MOUSE OFF
  1795.  
  1796. '..Clean up.
  1797. CloseProject
  1798. IF toolBarActive THEN CALL ToggleToolBar
  1799. CLEAR ALLOC
  1800. STOP
  1801.  
  1802. {*
  1803. ** Event handlers.
  1804. *}
  1805.  
  1806. {* Menu handler *}
  1807. handle_menu:
  1808.   theMenu = MENU(0)
  1809.   theItem = MENU(1)
  1810.  
  1811.   '..Project menu?
  1812.   IF theMenu = mProject THEN
  1813.     CASE
  1814.     theItem = iNew       : NewProject
  1815.     theItem = iOpen    : OpenProject
  1816.     theItem = iSave    : SaveProject
  1817.     theItem = iSaveAs  : SaveAs
  1818.     theItem = iToolBar : ToggleToolBar
  1819.     theItem = iAbout   : MsgBox "ReqEd v1.12, by David J Benn","Continue"
  1820.     theItem = iQuit       : QuitProgram
  1821.     END CASE
  1822.     RETURN
  1823.   END IF
  1824.  
  1825.   '..Window menu?
  1826.   IF theMenu = mWindow THEN
  1827.     CASE 
  1828.       theItem = iRedraw : WINDOW OUTPUT wdwID:CLS:RedrawGUIObjects
  1829.       theItem = iPreview : PreviewRequester    
  1830.       default : IF theItem <> 0 THEN CALL ModifyWindow(theItem)
  1831.     END CASE
  1832.     RETURN
  1833.   END IF  
  1834.  
  1835. '..No menu.
  1836. RETURN
  1837.  
  1838. {* Window (close-gadget) handler *}
  1839. handle_window:
  1840.   IF WINDOW(0) = toolWdw THEN CALL ToggleToolBar
  1841. RETURN
  1842.  
  1843. {* Gadget handler (for Tool Bar) *}
  1844. handle_gadget:
  1845.   theGadget = GADGET(1) 
  1846.  
  1847.   CASE
  1848.     theGadget = gButton      : boxStyle = RAISED
  1849.     theGadget = gString      : boxStyle = STRGAD
  1850.     theGadget = gLongInt     : boxStyle = STRGAD
  1851.     theGadget = gPotX           : boxStyle = RAISED
  1852.     theGadget = gPotY          : boxStyle = RAISED
  1853.     theGadget = gText          : boxStyle = NORMAL
  1854.     theGadget = gRaisedBox   : boxStyle = RAISED
  1855.     theGadget = gRecessedBox : boxStyle = RECESSED
  1856.   END CASE
  1857.  
  1858.   CreateGUIObj(theGadget, boxStyle)
  1859. RETURN
  1860.  
  1861. {* Mouse-handler (left mouse-button click) *}
  1862. handle_mouse:
  1863. ADDRESS theObject
  1864. SHORTINT edge
  1865.   IF WINDOW(0) = wdwID THEN
  1866.     '..Get current mouse coordinates.
  1867.     mouseX = MOUSE(1) : mouseY = MOUSE(2)
  1868.     '..On a GUI object's border? If so, resize object from specified edge.
  1869.     theObject = OnGUIObjBorder(mouseX, mouseY, @edge)
  1870.     IF theObject <> null THEN
  1871.     ResizeGUIObj(theObject, edge) 
  1872.     ELSE
  1873.         '..Within a GUI object's bounds?
  1874.         theObject = InsideGUIObj(mouseX, mouseY)
  1875.         IF theObject <> null THEN
  1876.             '..Show the object as being selected.
  1877.             SelectGUIObj(theObject)
  1878.           theKey$ = INKEY$
  1879.             CASE
  1880.         theKey$ = CHR$(DEL_key) OR theKey$ = CHR$(BKSPC_key) : DeleteGUIObj(theObject)
  1881.             theKey$ = CHR$(ENTER_key) : ModifyGUIObjVal(theObject)
  1882.             default : MoveGUIObj(theObject)
  1883.           END CASE    
  1884.         END IF
  1885.     END IF
  1886.   END IF
  1887. RETURN
  1888.  
  1889. END
  1890.